package org.wattdepot.cli.commands;

import java.util.ArrayList;
import java.util.List;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Provides the command to obtain fuel types.
 * 
 * @author David Joel Lazaro
 */
public class FuelTypesCommand implements Command {

  /**
   * Calls the fuelTypes method.
   * 
   * @param userInput The user input.
   * @param client The WattDepotClient
   * @return Returns the method call with the proper parameters.
   */
  public String doCommand(List<String> userInput, WattDepotClient client) {
    return fuelTypes(userInput, client);
  }

  /**
   * Generates a table where the first column contains fuel types and the second column is a
   * comma-delimited list of (non-virtual) sources generating power using that fuel type.
   * 
   * @param commandParam The input from user.
   * @param client The WattDepotClient
   * @return Returns the table of fuel types and the non-virtual sources.
   */
  private String fuelTypes(List<String> commandParam, WattDepotClient client) {
    StringBuffer buff = new StringBuffer();

    // Retrieves the source information
    String source = commandParam.get(1);

    // Checks to see if source is valid
    SourceChecker check = new SourceChecker();
    if (!check.sourceChecker(source, client)) {
      return "Invalid Source";
    }

    String format = " %1$-10s: %2$-7s \n";
    buff.append(String.format(format, "Fuel Type", "Sources"));

    try {
      Source theSource = client.getSource(source);
      if (theSource.isVirtual()) {

        List<String> LsfoSourceList = fuelSourceList(theSource, "LSFO", client);

        List<String> wasteSourceList = fuelSourceList(theSource, "waste", client);
        List<String> coalSourceList = fuelSourceList(theSource, "coal", client);
        buff.append(String.format(format, "LSFO", LsfoSourceList.toString()));
        buff.append(String.format(format, "waste", wasteSourceList.toString()));
        buff.append(String.format(format, "coal", coalSourceList.toString()));
      }

    }
    catch (NotAuthorizedException e) {
      e.printStackTrace();
    }
    catch (ResourceNotFoundException e) {
      e.printStackTrace();
    }
    catch (BadXmlException e) {
      e.printStackTrace();
    }
    catch (MiscClientException e) {
      e.printStackTrace();
    }

    return buff.toString();
  }

  /**
   * Recursive method that returns a list of all the sources and each of its sub sources.
   * 
   * @param source User inputed source.
   * @param fueltype User inputed fueltype.
   * @param client The WattDepot client.
   * @return Returns a list of all the sources and sub sources.
   */
  private List<String> fuelSourceList(Source source, String fueltype, WattDepotClient client) {
    List<String> mainList = new ArrayList<String>();

    try {
      // Retrieve the sub sources if source is virtual
      if (source.isVirtual()) {
        // sub sources list
        List<String> subsources = source.getSubSources().getHref();
        for (String list : subsources) {
          // Splits the sub-sources URL with '/' as delimiter
          String[] split = list.split("/");

          // adds all the recursed list to the main list
          mainList.addAll(fuelSourceList(client.getSource(split[5]), fueltype, client));
        }
      }
      else {
        // The subsequent non-virtual sources
        // checks for the specified fuel type
        if (source.getProperty("fuelType").equals(fueltype)) {
          mainList.add(source.getName());
        }
      }
    }
    catch (NotAuthorizedException e) {
      e.printStackTrace();
    }
    catch (ResourceNotFoundException e) {
      e.printStackTrace();
    }
    catch (BadXmlException e) {
      e.printStackTrace();
    }
    catch (MiscClientException e) {
      e.printStackTrace();
    }

    return mainList;
  }
}
